/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package server.serverDB;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 *
 * @author Александр Емельянов (mr.lex91@gmail.com)
 */
class FileDB {
    private String path;
    FileDB(String path)
    {
        this.path=path;
    }
    private String read(MappedByteBuffer fileRW)
    {
        byte[] b=new byte[8];
        fileRW.get(b);
        int len=8;
        while (len>0 && b[len-1]==0) len--;
        return new String(b,0,len);
    }
    private void write(MappedByteBuffer fileRW, String name, String data)
    {
        try {
            ByteBuffer b=ByteBuffer.allocate(16);
            b.put(name.getBytes("UTF-8"));
            b.position(8);
            b.put(data.getBytes("UTF-8"));
            fileRW.put(b.array());
        } catch (UnsupportedEncodingException ex) {}
    }
    public boolean Add(String name, String data, long begin, boolean useBegin)
    {
        try {
            File f=new File(path);
            RandomAccessFile raf= new RandomAccessFile(f,"rw");
            FileChannel fc=raf.getChannel();
            MappedByteBuffer fileRW=fc.map(FileChannel.MapMode.READ_WRITE, ((useBegin)?begin : f.length()), 16);
            write(fileRW,name,data);
            fc.close();
            raf.close();
            return true;
        } catch (IOException ex) {return false;}
    }
    public boolean Remove(long begin)
    {
        try {
            RandomAccessFile raf= new RandomAccessFile(new File(path),"rw");
            FileChannel fc=raf.getChannel();
            MappedByteBuffer fileRW=fc.map(FileChannel.MapMode.READ_WRITE, begin, 16);
            write(fileRW,"","");
            fc.close();
            raf.close();
            return true;
        } catch (IOException ex) {return false;}
    }
    public RecordInfo getRecordInfo(String name)
    {
        File f=new File(path);
        if (f.exists())
        try {
            RandomAccessFile raf= new RandomAccessFile(f,"rw");
            FileChannel fc=raf.getChannel();
            long begin=0;
            long len=1024;
            long fLen=f.length();
            long record=0;
            boolean recordFinded=false;
            MappedByteBuffer fileRW=null;
            while (true)
            {
                long curLen=(fLen==0)?16:(fLen>=begin+len)?len:fLen-begin;
                fileRW=fc.map(FileChannel.MapMode.READ_WRITE, begin, curLen);
                int readed=0;
                String nick="";
                String pas="";
                while (readed<curLen)
                {
                    nick=read(fileRW);
                    pas=read(fileRW);
                    if (nick.length()==0)
                    {
                        if (!recordFinded)
                        {
                            record=begin+readed;
                            recordFinded=true;
                        }
                    }
                    else if (nick.equals(name))
                    {
                        fc.close();
                        raf.close();
                        return new RecordInfo(pas,begin+readed,1);
                    }
                    readed+=16;
                }
                if (begin+curLen==fLen || fLen==0)
                {
                    fc.close();
                    raf.close();
                    return new RecordInfo("",record,((recordFinded)?2:0));
                }
            }
        } catch (IOException ex) {}
        return null;
    }
}
